﻿// -- MVC4WPF
// -- Copyright © 2009 Information Control Corporation
// -- Revision History:
// -- Version 0.9.0.0 First codeplex release  - Stephen Giffin

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EnvDTE;
using Microsoft.VisualStudio.TemplateWizard;
using MVC4WPF.Automation;
using MVC4WPF.Automation.Wizards;
using MVC4WPF.Automation.VisualStudio.Dialog;
using MVC4WPF.Automation.Data;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Forms;

namespace MVC4WPF.Automation.VisualStudio.Wizards
{
    public class MVC4WPFModelWizard : MVC4WPFWizardBase
    {
        #region MVC4WPFWizardBase Members

        /// <summary>
        /// Override method to execute the wizard.
        /// </summary>
        /// <param name="automationObject">The automation coming in by default provided by the system.</param>
        /// <param name="replacementsDictionary">A string/string dictionary that represents the replacement parameters for a template</param>
        /// <param name="runKind">The kind of wizard run</param>
        /// <param name="customParams">Any custom parameters sent in to the template</param>
        public override void ExecuteWizard(object automationObject, Dictionary<string, string> replacementsDictionary, WizardRunKind runKind, object[] customParams)
        {
            if (this.CurrentProject != null)
            {
                //construct a new dialog to display
                IModelDialog modelDialog = new ModelDialog();
                modelDialog.ViewPropertyBag.AvailableModelContracts = this.LoadContracts(typeof(IModel), this.CurrentProject).OrderBy(x => x.Name).ThenBy(x => x.FullName).ToList();
                modelDialog.ViewPropertyBag.DialogTitle = replacementsDictionary[FormatDictionaryParameterName(WizardParameters.DIALOGTITLE)];
                modelDialog.ViewPropertyBag.ItemName = replacementsDictionary[FormatDictionaryParameterName("rootname")];
                modelDialog.ViewPropertyBag.SelectName = "Create Model";

                //show the dialog
                if (modelDialog.ShowDialog() == false)
                {
                    //something happened to cancel the process. don't add item
                    this.ShouldAddItem = false;
                }
                else
                {
                    //gather information about the selected contract
                    ContractInformation contractInfo = ContractBuilder.BuildContract(modelDialog.ViewPropertyBag.SelectedModelContract);

                    //pull off the relevant pieces of information
                    List<ContractProperty> properties = contractInfo.Properties;
                    List<ContractEvent> events = contractInfo.Events;
                    List<ContractMethod> methods = contractInfo.Methods;

                    //add the interface parameter to the template
                    replacementsDictionary.Add(FormatDictionaryParameterName(WizardParameters.MODELCONTRACTNAME), contractInfo.FullName);

                    //get the location of the template files to process
                    string templateVersion = replacementsDictionary[FormatDictionaryParameterName(WizardParameters.TEMPLATEVERSION)];

                    //Using a helper method in the automation library to lookup the template folder based on the version of the template.
                    string templateFilePath = Automation.TemplateManager.GetTemplateFilePath(templateVersion);

                    string propertyTemplatePath = String.Format(@"{0}\{1}", templateFilePath, replacementsDictionary[FormatDictionaryParameterName(WizardParameters.PROPERTYTEMPLATENAME)]);
                    string eventTemplatePath = String.Format(@"{0}\{1}", templateFilePath, replacementsDictionary[FormatDictionaryParameterName(WizardParameters.EVENTTEMPLATENAME)]);
                    string methodTemplatePath = String.Format(@"{0}\{1}", templateFilePath, replacementsDictionary[FormatDictionaryParameterName(WizardParameters.METHODTEMPLATENAME)]);
                    string releasePropertyTemplatePath = String.Format(@"{0}\{1}", templateFilePath, replacementsDictionary[FormatDictionaryParameterName(WizardParameters.RELEASEPROPERTYTEMPLATENAME)]);
                    string releaseEventTemplatePath = String.Format(@"{0}\{1}", templateFilePath, replacementsDictionary[FormatDictionaryParameterName(WizardParameters.RELEASEEVENTTEMPLATENAME)]);

                    //executing the templates and storing the return values
                    TransformResults propertyResults = this.ExecuteTemplate<List<ContractProperty>>(propertyTemplatePath, properties);
                    TransformResults eventResults = this.ExecuteTemplate<List<ContractEvent>>(eventTemplatePath, events);
                    TransformResults methodResults = this.ExecuteTemplate<List<ContractMethod>>(methodTemplatePath, methods);
                    TransformResults releasePropertyResults = this.ExecuteTemplate<List<ContractProperty>>(releasePropertyTemplatePath, properties);
                    TransformResults releaseEventResults = this.ExecuteTemplate<List<ContractEvent>>(releaseEventTemplatePath, events);

                    //if any errors have occured, we need to bail
                    if (propertyResults.TransformErrors.HasErrors || eventResults.TransformErrors.HasErrors || methodResults.TransformErrors.HasErrors || releasePropertyResults.TransformErrors.HasErrors || releaseEventResults.TransformErrors.HasErrors)
                    {
                        MessageBox.Show(Properties.Resources.TemplateCompileErrors);
                        this.ShouldAddItem = false;
                        return;
                    }
                    else
                    {
                        //no errors, inject the corresponding parameters
                        replacementsDictionary.Add(FormatDictionaryParameterName(WizardParameters.PROPERTYTEMPLATECONTENT), propertyResults.Transformation);
                        replacementsDictionary.Add(FormatDictionaryParameterName(WizardParameters.EVENTTEMPLATECONTENT), eventResults.Transformation);
                        replacementsDictionary.Add(FormatDictionaryParameterName(WizardParameters.METHODTEMPLATECONTENT), methodResults.Transformation);
                        replacementsDictionary.Add(FormatDictionaryParameterName(WizardParameters.RELEASEPROPERTYTEMPLATECONTENT), releasePropertyResults.Transformation);
                        replacementsDictionary.Add(FormatDictionaryParameterName(WizardParameters.RELEASEEVENTTEMPLATECONTENT), releaseEventResults.Transformation);
                    }
                }
            }
        }

        #endregion
    }
}
